libostree: new API ostree_repo_remote_list_refs
authorGiuseppe Scrivano <gscrivan@redhat.com>
Wed, 22 Jul 2015 10:16:51 +0000 (12:16 +0200)
committerColin Walters <walters@verbum.org>
Fri, 24 Jul 2015 16:37:42 +0000 (12:37 -0400)
The new API permits to query a remote repository summary file and
retrieve the list of available refs.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
doc/ostree-sections.txt
src/libostree/ostree-repo-refs.c
src/libostree/ostree-repo.h
src/ostree/ot-remote-builtin-refs.c

index 7d412b46854b972945bfd382adb1f8669813af6c..a4d4f2e9bdcefcc2856e2b70ad9995b0fc246c88 100644 (file)
@@ -259,6 +259,7 @@ ostree_repo_write_content_async
 ostree_repo_write_content_finish
 ostree_repo_resolve_rev
 ostree_repo_list_refs
+ostree_repo_remote_list_refs
 ostree_repo_load_variant
 ostree_repo_load_commit
 ostree_repo_load_variant_if_exists
index 970f51919fef8556456f4465329b08585166374b..23e47fc70812c1bd8423a51247e6ef9a4733bb5b 100644 (file)
@@ -578,6 +578,81 @@ ostree_repo_list_refs (OstreeRepo       *self,
   return ret;
 }
 
+/**
+ * ostree_repo_remote_list_refs:
+ * @self: Repo
+ * @remote_name: Name of the remote.
+ * @out_all_refs: (out) (element-type utf8 utf8): Mapping from ref to checksum
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ */
+gboolean
+ostree_repo_remote_list_refs (OstreeRepo       *self,
+                              const char       *remote_name,
+                              GHashTable      **out_all_refs,
+                              GCancellable     *cancellable,
+                              GError          **error)
+{
+  g_autoptr(GBytes) summary_bytes = NULL;
+  gboolean ret = FALSE;
+  g_autoptr(GHashTable) ret_all_refs = NULL;
+
+  if (!ostree_repo_remote_fetch_summary (self, remote_name,
+                                         &summary_bytes, NULL,
+                                         cancellable, error))
+    goto out;
+
+  if (summary_bytes == NULL)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Remote refs not available; server has no summary file\n");
+      goto out;
+    }
+  else
+    {
+      g_autoptr(GVariant) summary = NULL;
+      g_autoptr(GVariant) ref_map = NULL;
+      GVariantIter iter;
+      GVariant *child;
+      ret_all_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+      summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
+                                          summary_bytes, FALSE);
+
+      ref_map = g_variant_get_child_value (summary, 0);
+
+      g_variant_iter_init (&iter, ref_map);
+      while ((child = g_variant_iter_next_value (&iter)) != NULL)
+        {
+          const char *ref_name = NULL;
+          g_autoptr(GVariant) csum_v = NULL;
+          char tmp_checksum[65];
+
+          g_variant_get_child (child, 0, "&s", &ref_name);
+
+          if (ref_name != NULL)
+            {
+              g_variant_get_child (child, 1, "(t@aya{sv})", NULL, &csum_v, NULL);
+
+              ostree_checksum_inplace_from_bytes (ostree_checksum_bytes_peek (csum_v),
+                                                  tmp_checksum);
+              g_hash_table_insert (ret_all_refs,
+                                   g_strdup (ref_name),
+                                   g_strdup (tmp_checksum));
+            }
+
+          g_variant_unref (child);
+        }
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_all_refs, &ret_all_refs);
+
+ out:
+  return ret;
+}
+
 gboolean      
 _ostree_repo_write_ref (OstreeRepo    *self,
                         const char    *remote,
index 84b0deb8b1fe40ced9f7bcd49c16402b60c629c1..992cf1e148d6ec52733a51c0fde5d73540fb5439 100644 (file)
@@ -291,6 +291,12 @@ gboolean      ostree_repo_list_refs (OstreeRepo       *self,
                                      GCancellable     *cancellable,
                                      GError          **error);
 
+gboolean ostree_repo_remote_list_refs (OstreeRepo       *self,
+                                       const char       *remote_name,
+                                       GHashTable      **out_all_refs,
+                                       GCancellable     *cancellable,
+                                       GError          **error);
+
 gboolean      ostree_repo_load_variant (OstreeRepo  *self,
                                         OstreeObjectType objtype,
                                         const char    *sha256, 
index c3dbbf2382474a56efaffd5c1fe0d94c6fd066e0..c1730bfa2ed8a88f8bf831aa5bb0487d6ec491be 100644 (file)
@@ -34,8 +34,8 @@ ot_remote_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError
   GOptionContext *context;
   glnx_unref_object OstreeRepo *repo = NULL;
   const char *remote_name;
-  g_autoptr(GBytes) summary_bytes = NULL;
   gboolean ret = FALSE;
+  g_autoptr(GHashTable) refs = NULL;
 
   context = g_option_context_new ("NAME - List remote refs");
 
@@ -51,39 +51,19 @@ ot_remote_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError
 
   remote_name = argv[1];
 
-  if (!ostree_repo_remote_fetch_summary (repo, remote_name,
-                                         &summary_bytes, NULL,
-                                         cancellable, error))
+  if (!ostree_repo_remote_list_refs (repo, remote_name, &refs, cancellable, error))
     goto out;
-
-  if (summary_bytes == NULL)
-    {
-      g_print ("Remote refs not available; server has no summary file\n");
-    }
   else
     {
-      g_autoptr(GVariant) summary = NULL;
-      g_autoptr(GVariant) ref_map = NULL;
-      GVariantIter iter;
-      GVariant *child;
-
-      summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
-                                          summary_bytes, FALSE);
+      g_autoptr(GList) ordered_keys = NULL;
+      GList *iter = NULL;
 
-      ref_map = g_variant_get_child_value (summary, 0);
+      ordered_keys = g_hash_table_get_keys (refs);
+      ordered_keys = g_list_sort (ordered_keys, (GCompareFunc) strcmp);
 
-      /* Ref map should already be sorted by ref name. */
-      g_variant_iter_init (&iter, ref_map);
-      while ((child = g_variant_iter_next_value (&iter)) != NULL)
+      for (iter = ordered_keys; iter; iter = iter->next)
         {
-          const char *ref_name = NULL;
-
-          g_variant_get_child (child, 0, "&s", &ref_name);
-
-          if (ref_name != NULL)
-            g_print ("%s\n", ref_name);
-
-          g_variant_unref (child);
+          g_print ("%s\n", (const char *) iter->data);
         }
     }